home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 21
/
CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso
/
CUCD
/
Magazine
/
C_Tutorial
/
Part-9
/
wb0
/
idcmp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-01-03
|
9KB
|
359 lines
#include "idcmp.h"
#include "drawwin.h"
#include "gadgets.h"
#include "loadsave.h"
#include "menu.h"
#include "toolwin.h"
#include "arexx.h"
#include<dos/rdargs.h>
#include<string.h>
#include<stdio.h>
#include<clib/dos_protos.h>
#include<clib/exec_protos.h>
#include<clib/gadtools_protos.h>
#include<clib/graphics_protos.h>
#include<clib/intuition_protos.h>
static void doGadgetUp(struct Window*, UWORD, struct Gadget*);
static int doMenuPick(struct Window*, UWORD);
static int doARexx(struct RexxMsg*, struct Window*);
static void new(struct Window*);
static int isCommand(char*, char*, char*, LONG*);
static void freeCommand(void);
/* Our message handling code */
void handleIDCMP()
{
char* text = "Hello World!";
int going = TRUE;
int drawing = FALSE;
ULONG drawsig, toolsig, arexxsig, gotsig;
struct Window* drawwin = getDrawWin();
drawsig = 1 << drawwin->UserPort->mp_SigBit;
arexxsig = getARexxSig();
while(going)
{
struct IntuiMessage* intuimsg;
/* Only include tool window signal mask if window is open */
toolsig = getToolSig();
/* Wait for messages to arrive */
gotsig = Wait(drawsig | toolsig | arexxsig);
/* Messages have arrived: loop through all of them */
/* Check messages from the drawing window first */
if(gotsig & drawsig)
{
while(intuimsg = GT_GetIMsg(drawwin->UserPort))
{
/* Copy the important bits of the message */
ULONG class = intuimsg->Class;
UWORD code = intuimsg->Code;
WORD mousex = intuimsg->MouseX;
WORD mousey = intuimsg->MouseY;
/* Reply when finished copying bits from message */
GT_ReplyIMsg(intuimsg);
/* Act on this message... */
switch(class)
{
case IDCMP_MOUSEBUTTONS:
switch(code)
{
case SELECTDOWN:
drawing = TRUE;
break;
case SELECTUP:
drawing = FALSE;
break;
}
/* break; omitted so we draw on click, too */
case IDCMP_MOUSEMOVE:
if(drawing)
{
Move(drawwin->RPort, mousex, mousey);
Text(drawwin->RPort, text, strlen(text));
}
break;
case IDCMP_MENUPICK:
going = doMenuPick(drawwin, code);
drawwin = getDrawWin();
drawsig = 1 << drawwin->UserPort->mp_SigBit;
break;
}
}
}
/* Now check messages from the tool window */
if(going && (gotsig & toolsig))
{
struct Window* toolwin = getToolWin();
while(toolwin && (intuimsg = GT_GetIMsg(toolwin->UserPort)))
{
/* Copy the important bits of the message */
ULONG class = intuimsg->Class;
UWORD code = intuimsg->Code;
APTR iaddr = intuimsg->IAddress;
/* Reply when finished copying bits from message */
GT_ReplyIMsg(intuimsg);
/* Act on this message... */
switch(class)
{
case IDCMP_CLOSEWINDOW:
closeToolWin();
/* Update our local toolwin, so we stop loop */
toolwin = NULL;
uncheckToolBar(drawwin);
break;
case IDCMP_REFRESHWINDOW:
/* You *MUST* remember to ask for and handle these refresh messages */
GT_BeginRefresh(toolwin);
GT_EndRefresh(toolwin, TRUE);
break;
case IDCMP_GADGETUP:
doGadgetUp(drawwin, code, (struct Gadget*)iaddr);
break;
case IDCMP_MENUPICK:
going = doMenuPick(drawwin, code);
/* Update our local toolwin, so we stop loop */
toolwin = getToolWin();
drawwin = getDrawWin();
drawsig = 1 << drawwin->UserPort->mp_SigBit;
break;
}
}
}
/* Now check messages from the ARexx port */
if(going && (gotsig & arexxsig))
{
struct RexxMsg* msg;
while(going && (msg = getARexxMsg()))
going = doARexx(msg, drawwin);
}
}
}
/* Process IDCMP_GADGETUP event */
static void doGadgetUp(struct Window* drawwin, UWORD code, struct Gadget* gad)
{
switch(gad->GadgetID)
{
case MYBUT_ID:
/* Our button was clicked! Set foreground to next pen colour */
nextFgPen(drawwin);
break;
case MYPAL_ID:
/* Our palette gadget was clicked! Set foreground to gadget colour */
setFgPen(drawwin, code);
break;
}
}
/* Process IDCMP_MENUPICK event */
static int doMenuPick(struct Window* drawwin, UWORD code)
{
UWORD menuCode, menuNumber, itemNumber;
/* Loop over all the menu selections in the menu code */
struct MenuItem* item;
for(menuCode = code;
menuCode != MENUNULL;
menuCode = item->NextSelect)
{
item = ItemAddress(drawwin->MenuStrip, menuCode);
/* Extract the menu number and menu item number from the menu code */
menuNumber = MENUNUM(menuCode);
itemNumber = ITEMNUM(menuCode);
/* Now decide what to do based on what menu item was selected */
switch(menuNumber)
{
case 0: /* Project menu */
switch(itemNumber)
{
case 0: /* Load */
return load();
case 1: /* Save */
save();
break;
case 3: /* New (item 2 is the bar!) */
new(drawwin);
break;
case 5: /* Quit (item 4 is the bar!) */
return FALSE;
}
break;
case 1: /* Pen menu */
switch(itemNumber)
{
case 0: /* Next */
nextFgPen(drawwin);
break;
case 1: /* Prev */
prevFgPen(drawwin);
break;
case 3: /* Reset (item 2 is the bar!) */
resetFgPen(drawwin);
break;
}
break;
case 2: /* Tools menu */
switch(itemNumber)
{
case 0: /* Screen Bar */
ShowTitle(drawwin->WScreen, item->Flags & CHECKED);
break;
case 1: /* Tool Bar */
/* Do the open or close */
if(item->Flags & CHECKED)
{
/* If the open fails, stop immediately */
if(!openToolWin())
return FALSE;
}
else
closeToolWin();
break;
}
}
}
/* Keep going */
return TRUE;
}
static void new(struct Window* win)
{
SetRast(win->RPort, 0);
}
/* Our RDArgs structure for use with ReadArgs() */
static struct RDArgs* myrdargs = NULL;
int createArgs()
{
if(myrdargs = AllocDosObject(DOS_RDARGS, NULL))
{
/* Disable prompting on stdin when "?" is the argument */
myrdargs->RDA_Flags = RDAF_NOPROMPT;
return TRUE;
}
else
printf("Error: could not allocate args for ARexx commands\n");
return FALSE;
}
void freeArgs()
{
if(myrdargs)
FreeDosObject(DOS_RDARGS, myrdargs);
}
/* The result of a ReadArgs() while parsing commands */
static struct RDArgs* rdargs = NULL;
/* Test if a string matches a command, using ReadArgs() */
static int isCommand(char* text, char* comm,
char* templ, LONG* args)
{
int clen = strlen(comm);
if(strnicmp(text, comm, clen) == 0)
{
/* Is the command followed by some whitespace? */
if(text[clen] == ' ' || text[clen] == '\t')
{
int tlen = strlen(text);
/* Set up our myrdargs so we can use ReadArgs() */
myrdargs->RDA_Source.CS_Buffer = text+clen+1;
myrdargs->RDA_Source.CS_Length = tlen-clen;
myrdargs->RDA_Source.CS_CurChr = 0;
myrdargs->RDA_DAList = NULL;
myrdargs->RDA_Buffer = NULL;
/* Temporarily end the string with a return... */
/* (Needed to get ReadArgs() to work properly) */
text[tlen] = '\n';
rdargs = ReadArgs(templ, args, myrdargs);
/* ... now we must reinstate the string's terminator */
text[tlen] = '\0';
return rdargs != NULL;
}
}
return NULL;
}
static void freeCommand()
{
if(rdargs)
{
FreeArgs(rdargs);
rdargs = NULL;
}
}
/* The maximum number of arguments for our commands */
#define MAX_ARGS (3)
#define COMM_QUIT "QUIT"
#define COMM_NEW "NEW"
#define COMM_PEN "PEN"
#define TEMPL_PEN "PEN/N"
enum PEN_ARGS { PEN_PEN };
#define COMM_DRAW "DRAW"
#define TEMPL_DRAW "X/N,Y/N,TEXT/F"
enum DRAW_ARGS { DRAW_X, DRAW_Y, DRAW_TEXT };
/* Process an ARexx message */
static int doARexx(struct RexxMsg* msg, struct Window* drawwin)
{
int going = TRUE;
/* By default, our reply will indicate an error */
LONG rc = 20;
char* res = NULL;
char* command = msg->rm_Args[0];
/* Parse the command */
if(stricmp(command, COMM_QUIT) == 0)
{
going = FALSE;
/* We recognised the command, so set rc to zero */
rc = 0;
res = "Hello Painter is quitting";
}
else if(stricmp(command, COMM_NEW) == 0)
{
new(drawwin);
rc = 0;
res = "Display cleared";
}
else
{
LONG args[MAX_ARGS];
int i;
for(i=0; i<MAX_ARGS; i++)
args[i] = NULL;
if(isCommand(command, COMM_PEN, TEMPL_PEN, args))
{
/* args[0] holds the pen number to use */
LONG* nptr = (LONG*)(args[PEN_PEN]);
setFgPen(drawwin, *nptr);
rc = 0;
res = "Pen set";
}
else if(isCommand(command, COMM_DRAW, TEMPL_DRAW, args))
{
/* args[DRAW_X] and args[DRAW_Y] hold the coordinate */
/* args[DRAW_TEXT] holds the text to be drawn */
LONG* xptr = (LONG*)(args[DRAW_X]);
LONG* yptr = (LONG*)(args[DRAW_Y]);
char* text = (char*)(args[DRAW_TEXT]);
Move(drawwin->RPort, *xptr, *yptr);
Text(drawwin->RPort, text, strlen(text));
rc = 0;
res = "Text drawn";
}
freeCommand();
}
replyARexxMsg(msg, rc, res);
return going;
}